package com.zd.lib.http.gson;

import android.util.Log;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.zd.lib.demo.ListEntity;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static android.R.attr.value;
import static com.zd.lib.http.retrofit.RetrofitUtils.builder;

/**
 * Created by zoudong on 2017/2/3.
 * 1.registerTypeAdapter    针对 List
 *     1.json 是 object 类型  直接  list.add（）
 *     2.类型不一致 跳过类型不一致的字段
 *  @version  1.2
 */
public class Json {

    public static Gson create() {
        GsonBuilder builder = new GsonBuilder();
        // 数据类型为List  服务器却返回Object 类型   fix bug 直接解析成list
        builder.registerTypeAdapter(List.class, new JsonDeserializer<List>() {
            @Override
            public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                Type itemType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0];
                System.out.println(json.isJsonNull());
                if (json.isJsonArray()) { //返回的是List 正常解析
                    JsonArray array = json.getAsJsonArray();
                    List list = new ArrayList<>();
                    for (int i = 0; i < array.size(); i++) {
                        JsonElement element = array.get(i);
                        justExceptionDeser(context, itemType, list, element);
                    }
                    return list;
                } else if (json.isJsonObject()) { //返回的是对象  将对象放在第一个
                    JsonObject object = json.getAsJsonObject();
                    ArrayList<Object> objects = new ArrayList<>();
                    if (object.size()>0) { //当返回 { } 就不应该 add   直接 返回空List
                        justExceptionDeser(context, itemType, objects, object);
                    }
                    return objects;
                } else {
                    //和接口类型不符，返回空List
                    return Collections.EMPTY_LIST;
                }
            }
        });

        return builder.create();
    }

    /**
     * 跳过异常解析
     * @param context
     * @param itemType
     * @param list
     * @param element
     */
    private static void justExceptionDeser(JsonDeserializationContext context, Type itemType, List list, JsonElement element) {
        try {   //解决我们定义的 object  服务器返回 array 导致app 其他字段无法解析，  解决 其他字段可以解析
            Object item = context.deserialize(element, itemType);
            list.add(item);
        } catch (Exception e) {
            e.printStackTrace(); //当解析 JSON 数据类型不一致时  try 异常 不影响其他字段的解析
        }
    }
}
